<!--
 * @描述: 网盘管理
 * @版权所有: 广东国星科技有限公司
 * @商业授权: www.mscodecloud.com
-->
<template>
  <div class="app-container">
    <div class="filter-container">
      <el-input v-model="listQuery.originalFilename" :placeholder="$t('file.original-filename')" clearable class="filter-input filter-item" @keyup.enter.native="handleFilter" />
      <el-input v-model="listQuery.content" :placeholder="$t('file.content')" clearable class="filter-input filter-item" @keyup.enter.native="handleFilter" />
      <el-button v-waves type="primary" class="filter-item" icon="el-icon-search" @click="handleFilter">
        {{ $t('common.query') }}
      </el-button>
      <el-button v-waves type="primary" class="filter-item" icon="el-icon-refresh-right" @click="handleReset">
        {{ $t('common.reset') }}
      </el-button>
      <el-button type="primary" class="filter-item" icon="el-icon-upload" @click="handleUpload">
        {{ $t('common.upload') }}
      </el-button>
      <el-button type="primary" class="filter-item" icon="el-icon-folder-add" @click="addNewRow">
        {{ $t('file.newfolder') }}
      </el-button>
      <el-button type="danger" plain class="filter-item" icon="el-icon-delete" @click="handleDelete">
        {{ $t('common.delete') }}
      </el-button>
    </div>
    <div style="margin-bottom: 10px;color: #1890FF;font-size: 12px">
      <span style="cursor: pointer" @click="goPrevious">{{ $t('file.goprevious') }}</span>
      <span style="float: right">{{ $t('file.loadall') }}{{ list.length }}{{ $t('file.piece') }}</span>
    </div>

    <el-table
      :key="tableKey"
      v-loading="listLoading"
      :data="list"
      border
      fit
      highlight-current-row
      style="width: 100%"
      @sort-change="sortChange"
      @selection-change="handleSelectionChange"
    >
      <el-table-column type="selection" width="40" />
      <el-table-column :label="$t('file.original-filename')" prop="originalFilename" min-width="220">
        <template slot-scope="scope">
          <img v-if="scope.row.type === 1" :key="editFileNameKey" src="@/assets/dir.png" style="vertical-align: middle;margin-right: 10px;">
          <img v-if="scope.row.type === 2" src="@/assets/file.png" style="vertical-align: middle;margin-right: 10px;">
          <el-input v-if="scope.row.isEdit" v-model="scope.row.originalFilename" style="display: inline-block; width: 65%" />
          <el-button v-if="scope.row.isEdit" circle icon="el-icon-check" size="mini" style="display: inline; margin-left: 3px;" type="success" @click="addFolder(scope.row.originalFilename)" />
          <el-button v-if="scope.row.isEdit" circle icon="el-icon-delete" size="mini" style="display: inline; margin-left: 3px;" type="danger" @click="cancelAddFile" />
          <span v-else class="spanLink" style="padding-left: 1px; text-align: center; cursor: pointer; color: #09aaff" @click="getListByParentId(scope.row)">{{ scope.row.originalFilename }}</span>
        </template>
      </el-table-column>
      <el-table-column :label="$t('file.file-size')" prop="fileSize" />
      <el-table-column :label="$t('file.content-type')" prop="contentType" />
      <el-table-column :label="$t('file.file-type')" prop="fileTypeCn" />
      <el-table-column :label="$t('common.create-time')" prop="createTime" sortable="custom" :class-name="getSortClass('createTime')" min-width="90">
        <template slot-scope="{row}">
          <span>{{ row.createTime | formatDate }}</span>
        </template>
      </el-table-column>
      <el-table-column :label="$t('common.operate')" align="center">
        <template slot-scope="{row,$index}">
          <el-button v-if="row.type === 2" :loading="downloadLoading" type="text" @click="handleDownload(row)">
            <i class="el-icon-download" />{{ $t('common.download') }}
          </el-button>
          <el-popover :ref="'popover-' + row.id" placement="top" width="160" :title="$t('common.confirm-delete')" trigger="click">
            <div>
              <el-button size="mini" @click="$refs[`popover-` + row.id].doClose()">{{ $t('common.cancel') }}</el-button>
              <el-button type="primary" size="mini" @click="$refs[`popover-` + row.id].doClose();handleDelete(row,$index)">{{ $t('common.confirm') }}</el-button>
            </div>
            <el-button slot="reference" type="text" style="margin-left: 10px">
              <i class="el-icon-delete" />{{ $t('common.delete') }}
            </el-button>
          </el-popover>
        </template>
      </el-table-column>
    </el-table>

    <el-dialog v-el-drag-dialog :title="$t('common.upload')" :visible.sync="dialogFormVisible">
      <el-form ref="dataForm" :rules="rules" :model="temp" :label-position="labelPosition" label-width="90px">
        <center>
          <el-upload ref="upload" :data="dataObj" :headers="elUploadHeaders" action="/api/file/file/uploadFile" :auto-upload="false" :on-success="handleSuccess" drag>
            <i class="el-icon-upload" />
            <div class="el-upload__text">
              {{ $t('file.drag') }}<em>{{ $t('file.clickupload') }}</em>
            </div>
          </el-upload>
        </center>
        <br>
        <el-form-item :label="$t('file.file-type')" prop="fileTypeName">
          <el-select v-model="temp.fileTypeName" :placeholder="$t('common.choose')" clearable style="width: 100%">
            <el-option v-for="item in fileTypeNameOptions" :key="item.value" :label="item.name" :value="item.value" />
          </el-select>
        </el-form-item>
      </el-form>
      <div slot="footer" class="dialog-footer">
        <el-button @click="dialogFormVisible = false">
          {{ $t('common.cancel') }}
        </el-button>
        <el-button type="primary" @click="uploadData()">
          {{ $t('common.confirm') }}
        </el-button>
      </div>
    </el-dialog>

    <el-dialog v-el-drag-dialog fullscreen :visible.sync="previewDialogVisible">
      <iframe v-if="pdfContent.length > 0" :src="pdfContent" width="100%" height="500px" frameborder="0" />
      <div v-if="txtContent.length > 0" v-html="txtContent" />
      <div v-if="wordContent.length > 0" v-html="wordContent" />
      <el-table v-if="excelContent.header.length > 0" :data="excelContent.results" border highlight-current-row style="width: 100%">
        <el-table-column v-for="item in excelContent.header" :key="item + Math.random()" :prop="item" :label="item" />
      </el-table>
    </el-dialog>
  </div>
</template>

<script>
import { queryFile, queryFileTypeName, deleteFile, downloadFile, addFolder } from '@/api/file'
import waves from '@/directive/waves' // waves directive
import elDragDialog from '@/directive/el-drag-dialog' // base on element-ui
import qs from 'qs'
import { saveAs } from 'file-saver'
import { getToken } from '@/utils/auth'
import mammoth from 'mammoth'
import XLSX from 'xlsx'

export default {
  name: 'UploadDownload',
  directives: { waves, elDragDialog },
  data() {
    return {
      labelPosition: 'right',
      tableKey: 0,
      list: [],
      total: 0,
      listLoading: true,
      listQuery: {
        currentPage: 1,
        pageSize: 1000,
        originalFilename: undefined,
        content: undefined,
        sorter: 'createTime_descend'
      },
      fileTypeNameOptions: [],
      multipleSelection: [],
      temp: {
        id: undefined
      },
      dialogFormVisible: false,
      dialogStatus: '',
      rules: {
        fileTypeName: [{ required: true, validator: this.checkFileTypeName, trigger: 'change' }]
      },
      downloadLoading: false,
      elUploadHeaders: { 'Authorization': 'Bearer ' + getToken() },
      dataObj: { },
      editFileNameKey: 1,
      previewDialogVisible: false,
      txtContent: '',
      pdfContent: '',
      wordContent: '',
      excelContent: {
        header: [],
        results: []
      },
      previousId: 0,
      fileId: undefined
    }
  },
  created() {
    if (window.innerWidth < 700) {
      this.labelPosition = 'top'
    }
    this.getList()
  },
  methods: {
    getList() {
      this.listLoading = true
      this.listQuery.parentId = 0
      this.listQuery.publicResource = 2
      this.listQuery.status = 1
      queryFile(this.listQuery).then(response => {
        this.list = response.data.list
        this.listLoading = false
      })
    },
    handleFilter() {
      this.listQuery.currentPage = 1
      this.listQuery.parentId = 0
      this.listQuery.previousId = undefined
      this.getList()
      this.editFileNameKey = 1
    },
    handleReset() {
      this.listQuery.originalFilename = ''
      this.listQuery.content = ''
      this.handleFilter()
    },
    sortChange(data) {
      const { prop, order } = data
      if (prop === 'createTime') {
        this.sortByCreateTime(order)
      }
    },
    sortByCreateTime(order) {
      if (order === 'ascending') {
        this.listQuery.sorter = 'createTime_ascend'
      } else {
        this.listQuery.sorter = 'createTime_descend'
      }
      this.handleFilter()
    },
    handleSelectionChange(val) {
      this.multipleSelection = val
    },
    resetTemp() {
      this.temp = {
        id: undefined
      }
    },
    handleUpload() {
      this.resetTemp()
      queryFileTypeName().then(fileResponse => {
        this.fileTypeNameOptions = fileResponse.data
        this.dialogFormVisible = true
        this.$nextTick(() => {
          this.$refs['dataForm'].clearValidate()
          this.$refs.upload.clearFiles()
        })
      })
    },
    uploadData() {
      if (this.$refs.upload.uploadFiles.length === 0) {
        this.handleWarning(this.$t('file.isnotempty'))
        return
      }
      this.$refs['dataForm'].validate((valid) => {
        if (valid) {
          this.dataObj.id = this.$store.getters.id
          this.dataObj.fileType = this.temp.fileTypeName
          let parentId
          if (this.list[0]) {
            parentId = this.list[0].parentId
          } else {
            parentId = this.fileId ? this.fileId : 0
          }
          this.dataObj.parentId = parentId
          this.dataObj.publicResource = 2
          this.$refs.upload.submit()
        }
      })
    },
    handleSuccess() {
      this.dialogFormVisible = false
      this.handleReset()
    },
    goPrevious() {
      this.listLoading = true
      if (this.list[0]) {
        this.listQuery.parentId = undefined
        this.listQuery.previousId = this.list[0].parentId
      } else {
        this.listQuery.parentId = this.previousId
      }
      this.listQuery.publicResource = 2
      this.listQuery.status = 1
      queryFile(this.listQuery).then(response => {
        this.list = response.data.list
        this.listLoading = false
      })
    },
    addNewRow() {
      if (this.editFileNameKey > 1) {
        return
      }
      this.list.unshift({
        originalFilename: this.$t('file.newfolder'),
        fileSize: '-',
        contentType: '-',
        fileTypeCn: '-',
        createTime: '-',
        type: 1,
        isEdit: true
      })
      ++this.editFileNameKey
    },
    generateData({ header, results }) {
      this.excelContent.header = header
      this.excelContent.results = results
    },
    readerData(rawFile) {
      this.downloadLoading = true
      return new Promise((resolve, reject) => {
        const reader = new FileReader()
        reader.onload = e => {
          const data = e.target.result
          const workbook = XLSX.read(data, { type: 'array' })
          const firstSheetName = workbook.SheetNames[0]
          const worksheet = workbook.Sheets[firstSheetName]
          const header = this.getHeaderRow(worksheet)
          const results = XLSX.utils.sheet_to_json(worksheet, { defval: '' })
          this.generateData({ header, results })
          this.downloadLoading = false
          resolve()
        }
        reader.readAsArrayBuffer(rawFile)
      })
    },
    getHeaderRow(sheet) {
      const headers = []
      const range = XLSX.utils.decode_range(sheet['!ref'])
      let C
      const R = range.s.r
      /* start in the first row */
      for (C = range.s.c; C <= range.e.c; ++C) { /* walk every column in the range */
        const cell = sheet[XLSX.utils.encode_cell({ c: C, r: R })]
        /* find the cell in the first row */
        // let hdr = 'UNKNOWN ' + C // <-- replace with your desired default
        let hdr = ' '
        if (cell && cell.t) hdr = XLSX.utils.format_cell(cell)
        headers.push(hdr)
      }
      return headers
    },
    getListByParentId(row) {
      if (row.type === 1) {
        this.listLoading = true
        this.listQuery.id = row.id
        this.listQuery.parentId = undefined
        this.listQuery.previousId = undefined
        this.listQuery.publicResource = 2
        this.listQuery.status = 1
        queryFile(this.listQuery).then(response => {
          this.list = response.data.list
          this.previousId = row.parentId
          this.listQuery.id = undefined
          this.fileId = row.id
          this.listLoading = false
        })
      } else {
        this.downloadLoading = true
        const listQueryData = {}
        listQueryData.originalFilename = row.originalFilename
        listQueryData.url = row.url
        downloadFile(qs.stringify(listQueryData)).then(response => {
          if (response.size === 0) {
            this.handleWarning(this.$t('file.cannotfind'))
          } else {
            const suffix = row.originalFilename.substring(row.originalFilename.toLowerCase().lastIndexOf('.') + 1)
            if (suffix === 'txt') {
              this.wordContent = ''
              this.pdfContent = ''
              this.excelContent = { header: [], results: [] }
              const that = this
              var reader = new FileReader()
              reader.readAsText(response)
              reader.onload = function(event) {
                that.txtContent = reader.result
              }
              this.previewDialogVisible = true
            } else if (suffix === 'pdf') {
              this.txtContent = ''
              this.wordContent = ''
              this.excelContent = { header: [], results: [] }
              const blob = new Blob([response], { type: 'application/pdf' })
              const fileURL = URL.createObjectURL(blob)
              const url = encodeURIComponent(fileURL)
              this.pdfContent = `/mscodevue/static/pdf/web/viewer.html?file=${url}`
              this.previewDialogVisible = true
            } else if (suffix === 'doc' || suffix === 'docx') {
              this.txtContent = ''
              this.pdfContent = ''
              this.excelContent = { header: [], results: [] }
              const that = this
              var file = response
              // eslint-disable-next-line
              var reader = new FileReader()
              reader.readAsArrayBuffer(file)
              reader.onload = function(e) {
                const buffer = e.target.result
                mammoth.convertToHtml({ arrayBuffer: buffer }).then((result) => {
                  that.wordContent = result.value
                }).done()
              }
              this.previewDialogVisible = true
            } else if (suffix === 'xls' || suffix === 'xlsx') {
              this.txtContent = ''
              this.wordContent = ''
              this.pdfContent = ''
              this.readerData(response)
              this.previewDialogVisible = true
            }
          }
        })
        this.downloadLoading = false
      }
    },
    addFolder(originalFilename) {
      this.list[0].isEdit = false
      let parentId
      if (this.list[1]) {
        parentId = this.list[1].parentId
      } else {
        parentId = this.fileId ? this.fileId : 0
      }
      const publicResource = 2
      addFolder(this.$store.getters.id, originalFilename, parentId, publicResource).then(response => {
        if (response.message === 'success') {
          this.$message({
            message: this.$t('file.newfolder') + this.$t('common.success'),
            type: 'success'
          })
          this.handleReset()
        } else {
          this.handleWarning(response)
        }
      })
      this.editFileNameKey = 1
    },
    cancelAddFile() {
      this.list.shift()
      this.editFileNameKey = 1
    },
    handleDelete(row, index) {
      if (row.id) {
        this.delete(row.id)
      } else {
        if (this.multipleSelection.length === 0) {
          this.handleWarning(this.$t('common.choose-delete'))
          return
        }
        this.$confirm(this.$t('common.confirm-batch-delete'), this.$t('common.batch-delete'), {
          confirmButtonText: this.$t('common.confirm'),
          cancelButtonText: this.$t('common.cancel'),
          type: 'warning'
        }).then(() => {
          this.delete(this.multipleSelection.map(item => { return item.id }).join(','))
        }).catch(() => {})
      }
    },
    delete(deleteArray) {
      deleteFile(deleteArray).then(response => {
        if (response.message === 'success') {
          this.$message({
            message: this.$t('common.delete-success'),
            type: 'success',
            duration: 2000
          })
          this.handleReset()
        } else {
          this.handleWarning(response)
        }
      })
    },
    handleDownload(row) {
      this.downloadLoading = true
      const listQueryData = {}
      listQueryData.originalFilename = row.originalFilename
      listQueryData.url = row.url
      downloadFile(qs.stringify(listQueryData)).then(response => {
        if (response.size === 0) {
          this.handleWarning(this.$t('file.cannotfind'))
        } else {
          saveAs(response, row.originalFilename)
        }
      })
      this.downloadLoading = false
    },
    getSortClass: function(key) {
      const sorter = this.listQuery.sorter
      return sorter === `${key}_ascend` ? 'ascending' : 'descending'
    },
    handleWarning(response) {
      this.$message({
        message: response.message || response,
        type: 'warning',
        duration: 2000
      })
    },
    checkFileTypeName(rule, value, callback) {
      if (!value || value.length === 0) {
        return callback(new Error(this.$t('file.fileTypeName-required')))
      } else {
        callback()
      }
    }
  }
}
</script>
<style lang="scss" scoped>
  .spanLink:hover {
    color: #09aaff
  }
</style>
